package org.team4.util;

import java.math.BigDecimal;

/**
 * <p><b>运算类</b></p>
 * <p>
 * 此类提供精确浮点数计算，以适应诸如货币运算等商业数据运算。<br>
 * </p>
 * @author zhangqiang
 * @version v1.0.0 Mar 4, 2011
 */
public final class Arithmetic {
	//默认除法运算精度,小数点后精确到第10位
    public static final int DEFAULT_DIV_SCALE = 10;

    private Arithmetic(){}
    
    /**
     * 当参数v1小于参数v2时为真
     */
    public static Boolean lt(Double v1, Double v2){
    	return v1.compareTo(v2) < 0;
    }
    /**
     * 当参数v1大于参数v2时为真
     */
    public static Boolean gt(Double v1, Double v2){
    	return v1.compareTo(v2) > 0;
    }
    /**
     * 当参数v1等于参数v2时为真
     */
    public static Boolean eq(Double v1, Double v2){
    	return v1.compareTo(v2) < 0;
    }
    /**
     * 精确的加法运算。
     */
    public static Double add(Double v1,Double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }
    /**
     * 精确的减法运算。
     */
    public static Double sub(Double v1,Double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }
    /**
     * 精确的乘法运算。
     */
    public static Double mul(Double v1,Double v2){
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }
    /**
     * (相对)精确的除法运算，当发生除不尽的情况时，精确到
     * 小数点以后10位，以后的数字四舍五入。
     */
    public static Double div(Double v1, Double v2){
        return div(v1,v2,DEFAULT_DIV_SCALE);
    }
    /**
     * (相对)精确的除法运算。当发生除不尽的情况时，由scale参数指
     * 定精度，精度以后的数字四舍五入。
     */
    public static Double div(Double v1, Double v2, int scale){
        if(scale<0){
            throw new IllegalArgumentException(
                "The scale must be a positive integer or zero, but: "+scale);
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    /**
     * 精确的小数位四舍五入处理。
     */
    public static Double round(Double v, int scale){
        if(scale<0){
            throw new IllegalArgumentException(
                "The scale must be a positive integer or zero, but: "+scale);
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    
};
